package ljl.codetop;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;

/**
 * + - * %
 * 数字只有整数，可能有空白
 * todo 操，不会做
 * 我以为我看了四年 parser 可以轻松写出来了，but the answer is -- no, I can't
 */
public class _227_calculate {

    /**
     * does not work.
     */
    static class my_stupid_answer {
        int i;
        String buf;
        LinkedList<Integer> nums = new LinkedList<>();
        LinkedList<Character> ops = new LinkedList<>();
        public int calculate(String s) {
            int res = 0;
            buf = s.trim();
            while (i < buf.length()) {
                int num = scanInt();
                char op = buf.charAt(i);
                if (ops.size() == 0) {
                    nums.push(num);
                    ops.push(op);
                } else {
                    if (op == '+' || op == '-') {
                        char lastOp = ops.pop();
                        int num2 = nums.pop(), num1 = nums.pop();
                        int newNum;
                        if (lastOp == '+')
                            newNum = num1 + num2;
                        else
                            newNum = num1 - num2;
                        nums.push(newNum);
                        ops.push(op);
                    } else {

                    }
                }
            }
            return res;
        }

        int scanInt() {
            int res = buf.charAt(i) - '0';
            i++;
            char c;
            while (i < buf.length() && Character.isDigit((c = buf.charAt(i)))) {
                res = res * 10 + c - '0';
                i++;
            }
            return res;
        }
    }

    public int calculate(String s) {
        LinkedList<Integer> nums = new LinkedList<>();
        int num = 0;
        char sign = '+';
        for (int i = 0; i < s.length(); i++) {
            if (Character.isDigit(s.charAt(i)))
                num = num * 10 + s.charAt(i) - '0';
            if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == s.length() - 1) {
                switch (sign) {
                    case '+' -> nums.push(num);
                    case '-' -> nums.push(-num);
                    case '*' -> nums.push(nums.pop() * num);
                    case '/' -> nums.push(nums.pop() / num);
                }
                sign = s.charAt(i);
                num = 0;
            }
        }
        return nums.stream().mapToInt(Integer::valueOf).sum();
    }

    static class official {
        public int calculate(String s) {
            Deque<Integer> stack = new ArrayDeque<>();
            char preSign = '+';
            int num = 0;
            int n = s.length();
            for (int i = 0; i < n; ++i) {
                if (Character.isDigit(s.charAt(i))) {
                    num = num * 10 + s.charAt(i) - '0';
                }

                if (!Character.isDigit(s.charAt(i)) && s.charAt(i) != ' ' || i == n - 1){
                    switch (preSign) {
                        case '+' -> stack.push(num);
                        case '-' -> stack.push(-num);
                        case '*' -> stack.push(stack.pop() * num);
                        default -> stack.push(stack.pop() / num);
                    }
                    preSign = s.charAt(i);
                    num = 0;
                }
            }
            int ans = 0;
            while (!stack.isEmpty()) {
                ans += stack.pop();
            }
            return ans;
        }
    }

}
